package com.pine.app.module.security.oauth.plugin.impl.loginTGT;

import com.pine.app.module.security.core.common.AuthConstant;
import com.pine.app.module.security.core.common.CookieUtil;
import com.pine.app.module.security.core.common.RequestUtils;
import com.pine.app.module.security.core.common.enums.ErrorType;
import com.pine.app.module.security.core.common.enums.ResponseProduceType;
import com.pine.app.module.security.oauth.exception.AuthenticationException;
import com.pine.app.module.security.oauth.plugin.AbstractProcessPlugin;
import com.pine.app.module.security.oauth.plugin.Plugin;
import com.pine.app.module.security.oauth.config.properties.OAuth2Properties;
import com.pine.app.module.security.oauth.support.code.AuthorizationCodeRequest;
import com.pine.app.module.security.oauth.support.code.HttpAuthorizationCodeRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author xiaoyuan
 * @create 2020/3/6 22:35
 **/
@Slf4j
public class LoginAPITGTPlugin extends AbstractProcessPlugin {

    private OauthTgtService oauthTgtService;
    private OAuth2Properties.Tgt tgt;
    private String p_tgt;
    //转换为授权码请求对象
    private AuthorizationCodeRequest authorizationCodeRequest;

    public LoginAPITGTPlugin(OAuth2Properties.Tgt tgt) {
        this.tgt = tgt;
    }

    @Autowired
    public void setOauthTgtService(OauthTgtService oauthTgtService) {
        this.oauthTgtService = oauthTgtService;
    }

    public void setTgt(OAuth2Properties.Tgt tgt) {
        this.tgt = tgt;
    }

    @Override
    public void init() {
        log.info("登陆接口的票据处理插件初始化成功");
    }

    @Override
    public void prepare(HttpServletRequest request, HttpServletResponse response, Object o) throws ServletException, IOException {
       // log.info("开始执行登陆接口的票据处理插件");
        //添加一个票据   目的是异常后跳转页面后也有此票据
        request.setAttribute(AuthConstant.OAUTH_SERVER_COOKIE_KEY, oauthTgtService.createTGT());
        //转换为授权码请求对象
        authorizationCodeRequest = new HttpAuthorizationCodeRequest(request);
        //获取参数中的票据
        p_tgt = authorizationCodeRequest.getParameter(AuthConstant.OAUTH_SERVER_COOKIE_KEY).orElse("");
        String error_message = "";
        if (StringUtils.isEmpty(p_tgt) || !this.oauthTgtService.checkTGT(p_tgt)) {
         //   throw new AuthenticationException(ErrorType.ILLEGAL_REQUEST, ResponseProduceType.HTML, AuthConstant.DEFAULT_LOGIN_PATH);
            error_message =ErrorType.ILLEGAL_REQUEST.message();
        }
        if(StringUtils.isNotBlank(error_message)){
            request.setAttribute(AuthConstant.DEFAULT_LOGIN_ERROR_KEY,error_message);
            RequestDispatcher dispatcher = request.getRequestDispatcher(AuthConstant.DEFAULT_LOGIN_PATH);
            dispatcher.forward(request, response);
        }
    }

    @Override
    public void complete(HttpServletRequest request, HttpServletResponse response, Object o) {
        OauthTgtDTO tgtDTO = new OauthTgtDTO();
        tgtDTO.setId(p_tgt);
        tgtDTO.setExpire(tgt.getExpire() / 1000);
        tgtDTO.setLoginName(authorizationCodeRequest.getParameter(AuthConstant.username).get());
        tgtDTO.setRememberMe("true".equalsIgnoreCase(request.getParameter("rememberMe")) ? true : false);
        tgtDTO.setRequestIp(RequestUtils.getIpAddr(request));
        tgtDTO.setUserAgent(request.getHeader("User-Agent"));
        //登陆成功后添加票据到cookie中
        CookieUtil.setCookie(response, AuthConstant.OAUTH_SERVER_COOKIE_KEY, p_tgt, 604800, true, false);
        //绑定票据和用户的关系到缓存
        this.oauthTgtService.save(tgtDTO);
        this.oauthTgtService.remove((String) request.getAttribute(AuthConstant.OAUTH_SERVER_COOKIE_KEY));
        request.removeAttribute(AuthConstant.OAUTH_SERVER_COOKIE_KEY);
    }

    @Override
    public int getOrder() {
        return 10;
    }

    @Override
    public boolean matcher(HttpServletRequest request, Plugin plugin) {
        return matcher("loginAPI", plugin);
    }
}
